package com.xy.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.xy.entity.CertificateApplyEntity;
import com.xy.entity.CertificateTempEntity;
import com.xy.entity.CertificateTypeEntity;
import com.xy.excel.CertificateApplyExcel;
import com.xy.excel.PersonnelExcelTemp;
import com.xy.excel.VehicleExcelTemp;
import com.xy.mapper.CertificateApplyMapper;
import com.xy.service.ICertificateApplyService;
import com.xy.service.ICertificateTempService;
import com.xy.service.ICertificateTypeService;
import com.xy.utils.IdCarUtils;
import com.xy.utils.IdCardCheckUtil;
import com.xy.utils.SmsNotifiUtil;
import com.xy.vo.CertificateApplyVO;
import com.xy.vo.quer.AuditParam;
import com.xy.vo.quer.CertificateApplyPageQuery;
import com.xy.vo.result.MateVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.excel.support.ExcelException;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.IResultCode;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.api.ResultCode;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.resource.feign.IOssClient;
import org.springblade.resource.feign.ISmsClient;
import org.springblade.system.cache.DictBizCache;
import org.springblade.system.entity.DictBiz;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotBlank;
import java.io.File;
import java.io.FilenameFilter;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.xy.constants.CertificateTypeKey.*;
import static com.xy.utils.BigDecimalUtil.getBigDecimal;
import static com.xy.utils.StrUtil.trim;


/**
 * @BelongsPackage: com.xy.service
 * @Author: WK
 * @CreateTime: 2023-07-19
 * @Description:
 * @Version: 1.0
 */


@Service
@Slf4j
@AllArgsConstructor
public class CertificateApplyServiceImpl extends BaseServiceImpl<CertificateApplyMapper, CertificateApplyEntity> implements ICertificateApplyService {


	private final ICertificateTypeService certificateTypeService;


	private final ICertificateTempService certificateTempService;

	private final ISmsClient smsClient;
	private final IOssClient ossClient;
	private final BladeRedis bladeRedis;


	@Override
	public IPage<CertificateApplyVO> selectCertificateApplyPage(IPage<CertificateApplyVO> page, CertificateApplyVO certificateApply) {

		return page.setRecords(baseMapper.selectCertificateApplyPage(page, certificateApply));
	}

	@Override
	public List<CertificateApplyExcel> exportCertificateApply(Wrapper<CertificateApplyEntity> queryWrapper) {
		List<CertificateApplyExcel> certificateApplyList = baseMapper.exportCertificateApply(queryWrapper);
		//certificateApplyList.forEach(certificateApply -> {
		//	certificateApply.setTypeName(DictCache.getValue(DictEnum.YES_NO, CertificateApply.getType()));
		//});
		return certificateApplyList;
	}

	@Override
	public Boolean matchingFileL(String directoryPath) {
		File directory = new File(directoryPath);
		FilenameFilter imageFilter = new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				String lowercaseName = name.toLowerCase();
				return lowercaseName.endsWith(".jpg") || lowercaseName.endsWith(".jpeg")
					|| lowercaseName.endsWith(".png") || lowercaseName.endsWith(".gif");
			}
		};

		File[] imageFiles = directory.listFiles(imageFilter);
		if (Func.isEmpty(imageFiles)) {
			throw new ServiceException("未找到要匹配的图片!");

		}
		if (imageFiles != null) {
			LambdaQueryChainWrapper<CertificateApplyEntity> queryWrapper = lambdaQuery().in(CertificateApplyEntity::getBizCode, PER_CERTIFICATE_TYPE, SER_CERTIFICATE_TYPE);
			List<CertificateApplyEntity> list = queryWrapper.list();
			if (Func.isEmpty(list)) {
				throw new ServiceException("未找到要匹配的人员证件信息!");
			}
			Map<String, CertificateApplyEntity> entityMap = list.stream().filter(o -> Func.isNotEmpty(o.getIdCard())).collect(Collectors.toMap(CertificateApplyEntity::getIdCard, s -> s, (v1, v2) -> v1));
			for (File file : imageFiles) {
				String name = file.getName();
				if (Func.isEmpty(name)) {
					continue;
				}
				String fileName = trim(file.getName());
				String idcar = Func.split(fileName, ".")[0];
				CertificateApplyEntity certificateApplyEntity = entityMap.get(idcar);
				if (Func.isEmpty(certificateApplyEntity)) {
					continue;
				}
				R r1 = smsClient.update_file(file);
				if (log.isDebugEnabled()) {
					log.debug(certificateApplyEntity.getName() + ": " + certificateApplyEntity.getIdCard() + "   匹配图片结果====================" + r1);
				}
				if (r1.isSuccess() && !Func.isNull(r1.getData()) && Func.isNotEmpty(r1.getData())) {
					certificateApplyEntity.setUrl((String) r1.getData());
					updateById(certificateApplyEntity);
				}
			}
		}
		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean audit(AuditParam auditParam) {
		CertificateApplyEntity entity = getById(auditParam.getId());
		if (Func.isEmpty(entity)) {
			throw new ServiceException("数据不存在!");
		}
		if (Func.equals(entity.getBizStatus(), 2)) {
			throw new ServiceException("证件申请已被驳回无法重新审核，需重新提交审核!");
		}
		if (Func.equals(entity.getBizStatus(), 1)) {
			if (Func.equals(entity.getBizCode(), CAR_CERTIFICATE_TYPE)) {
				throw new ServiceException("车牌号: " + entity.getLicensePlate() + "证件申请,已审核通过了,无需在审");
			} else {
				throw new ServiceException(entity.getName() + " 证件申请,已审核通过了,无需在审");
			}
		}
		if (Func.isEmpty(entity.getAuditorCount()) || entity.getAuditorCount() == 0) {
			entity.setAuditorCount(1);
		}
		entity.setBizStatus(auditParam.getBizStatus());
		entity.setRemark(auditParam.getRemark());
		entity.setAuditor(AuthUtil.getUserId());
		entity.setAuditorBy(AuthUtil.getUserName());
		if (auditParam.getBizStatus() == 1) {
			CertificateTypeEntity entity1 = certificateTypeService.getById(entity.getCertificateTypeId());
			String serialStr = getSerialStr(entity1);
			if(Func.isNotEmpty(serialStr)){
				entity.setSerialNumber(serialStr);
			}
			String cardNumberStr = getCardNumberStr(entity1);
			if(Func.isNotEmpty(cardNumberStr)){
				entity.setCardNumber(cardNumberStr);
			}
		}

		boolean res = updateById(entity);
		if (res) {
			if (auditParam.getBizStatus() == 1) {
				String msg = String.format("尊敬的%s,您申请的证件已通过审核。", Func.equals(entity.getBizCode(), CAR_CERTIFICATE_TYPE) ? entity.getLinkman() : entity.getName());
				String send = SmsNotifiUtil.send(Collections.singletonList(entity.getPhone()), msg);
				if (log.isDebugEnabled()) {
					log.debug("证件申请驳回通知结果：{}", send);
				}
			}
			if (auditParam.getBizStatus() == 2) {
				String msg = String.format("尊敬的%s,您提交的证件申请信息审核未通过。如有问题，请联系证件申报负责人;未通过原因: %s", Func.equals(entity.getBizCode(), CAR_CERTIFICATE_TYPE) ? entity.getLinkman() : entity.getName(), auditParam.getRemark());
				String send = SmsNotifiUtil.send(Collections.singletonList(entity.getPhone()), msg);
				if (log.isDebugEnabled()) {
					log.debug("证件申请驳回通知结果：{}", send);
				}
			}
		}

		return res;
	}


	public String getSerialStr(CertificateTypeEntity entity){
		String key ="crm:type:serial".concat(Func.toStr(entity.getId()));
		Object o = bladeRedis.get(key);

		if(Func.isEmpty(o)){
			if(Func.isEmpty(entity.getSerialNumber())){
				return  "";
			}
			bladeRedis.set(key,entity.getSerialNumber());
			String newStrNum = String.format("%0"+entity.getSerialNumber().length()+"d", Func.toInt(entity.getSerialNumber()));
			String concat = entity.getSerialPrefix().concat(newStrNum);
			return concat;
		}
		int i = Func.toInt(o) + 1;
		bladeRedis.set(key,i);
		String newStrNum = String.format("%05d",i);
		return  entity.getSerialPrefix().concat(newStrNum);
	}

	public String getCardNumberStr(CertificateTypeEntity entity){
		String key ="crm:type:card:number".concat(Func.toStr(entity.getId()));
		Object o = bladeRedis.get(key);
		if(Func.isEmpty(o)){
			if(Func.isEmpty(entity.getCardNumber())){
				return  "";
			}
			int i = Func.toInt(entity.getCardNumber()) + 1;
			bladeRedis.set(key,i);
			return Func.toStr(i);
		}
		int i = Func.toInt(o) + 1;
		bladeRedis.set(key,i);
		return Func.toStr(i);
	}

	public static void main(String[] args) {
		String a ="00011";
		String b ="%0"+a.length()+"d";
		String format = String.format(b, Func.toInt(a));
		System.out.println(format);
	}


	@Override
	public List<CertificateApplyEntity> getExportData(CertificateApplyPageQuery param, @NotBlank String bizCode) {
		LambdaQueryChainWrapper<CertificateApplyEntity> queryWrapper = lambdaQuery().eq(CertificateApplyEntity::getBizCode, bizCode)
			.eq(Func.isNoneBlank(param.getName()), CertificateApplyEntity::getName, param.getName())
			.eq(Func.isNoneBlank(param.getLinkman()), CertificateApplyEntity::getLinkman, param.getLinkman())
			.eq(Func.isNoneBlank(param.getLicensePlate()), CertificateApplyEntity::getLicensePlate, param.getLicensePlate())
			.eq(Func.isNoneBlank(param.getPhone()), CertificateApplyEntity::getPhone, param.getPhone());
		List<CertificateApplyEntity> list = queryWrapper.list();
		if (Func.isEmpty(list)) {
			return Collections.emptyList();
		}
		return list;
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public void importVeData(List<VehicleExcelTemp> data, Boolean isCovered, String cid) {
		if (Func.isNull(data.get(0).getLicensePlate())) {
			throw new ExcelException("导入数据模板不正确!");
		}
		List<CertificateTypeEntity> types = getTypes(CAR_CERTIFICATE_TYPE);
		if (Func.isEmpty(types)) {
			throw new ExcelException("您没有车俩证件类型的申请权限!");
		}
		Map<String, CertificateTypeEntity> typeEntityMap = new HashMap<>();
		if (Func.isNotEmpty(types)) {
			typeEntityMap = types.stream().collect(Collectors.toMap(o -> trim(o.getTypeName()), s -> s, (v1, v2) -> v1));
		}
		if (Func.isNotEmpty(data)) {
			List<CertificateApplyEntity> list = getApplys(CAR_CERTIFICATE_TYPE,cid);
			Map<String, String> map = new HashMap<>();
			if (Func.isNotEmpty(list)) {
				map = list.stream().collect(Collectors.toMap(CertificateApplyEntity::getLicensePlate, t -> t.getLicensePlate(), (k1, k2) -> k1));
			}

			Map<String, CertificateTempEntity> tempMap = new HashMap<>();
			Map<String, String> tempCountMap = new HashMap<>();
			List<CertificateApplyEntity> addData = new ArrayList<>();
			for (int i= 0; i<data.size();i++) {
				VehicleExcelTemp vehicleExcel = data.get(i);
				if (Func.isEmpty(vehicleExcel.getLicensePlate())) {
					throw new ExcelException("第"+(i+2)+"行："+"请填入车牌号!");
				}
				if (Func.isEmpty(vehicleExcel.getLinkman())) {
					throw new ExcelException("第"+(i+2)+"行："+"请填入联系人!");
				}
				//if (Func.isEmpty(vehicleExcel.getVehicleModel())) {
				//	throw new ExcelException("请填入车型!");
				//}
				if (Func.isEmpty(vehicleExcel.getType())) {
					throw new ExcelException("第"+(i+2)+"行："+"请输入申请证件名称!");
				}
				if (Func.isEmpty(vehicleExcel.getNumberOfSeats())) {
					throw new ExcelException("第"+(i+2)+"行："+"请填入车俩人数!");
				}
				if (Func.isEmpty(vehicleExcel.getPhone())) {
					throw new ExcelException("第"+(i+2)+"行："+"请填入联系电话!");
				}
				if (IdCardCheckUtil.isPhone(vehicleExcel.getPhone()) && IdCardCheckUtil.isMobile(vehicleExcel.getPhone())) {
					throw new ExcelException("第"+(i+2)+"行："+vehicleExcel.getLicensePlate() + "联系电话不正确!");
				}
				String licensePlate = trim(vehicleExcel.getLicensePlate());
				String s = map.get(licensePlate);
				if (Func.notNull(s)) {
					throw new ExcelException("第"+(i+2)+"行："+"车牌号:" + licensePlate + ",已存在");
				}
				CertificateApplyEntity certificateApplyEntity = Objects.requireNonNull(BeanUtil.copy(vehicleExcel, CertificateApplyEntity.class));
				certificateApplyEntity.setStatus(3);
				certificateApplyEntity.setLicensePlate(licensePlate);
				certificateApplyEntity.setBizStatus(0);
				certificateApplyEntity.setAuditorCount(1);
				certificateApplyEntity.setBizCode(CAR_CERTIFICATE_TYPE);
				certificateApplyEntity.setAgentUserId(AuthUtil.getUserId());
				certificateApplyEntity.setAgentUser(AuthUtil.getUser().getUserName());
				if (Func.isNotEmpty(cid)) {
					certificateApplyEntity.setCreateUser(Func.toLong(cid));
				}
				if (Func.isNotEmpty(typeEntityMap)) {
					CertificateTypeEntity certificateTypeEntity = typeEntityMap.get(trim(vehicleExcel.getType()));
					if (Func.isNotEmpty(certificateTypeEntity)) {
						certificateApplyEntity.setCertificateTypeId(certificateTypeEntity.getId());
						CertificateTempEntity certificateTempEntity = tempMap.get(Func.toStr(certificateTypeEntity.getId()));
						String count = tempCountMap.get(Func.toStr(certificateApplyEntity.getCertificateTypeId()));
						if (Func.isEmpty(count)) {
							Long aLong = countBy(certificateTypeEntity.getId(), Func.toLong(cid));
							tempCountMap.put(Func.toStr(certificateTypeEntity.getId()), Func.toStr(aLong));
						}
						if (Func.isEmpty(certificateTempEntity)) {
							CertificateTempEntity typeTemp = getTypeTemp(certificateTypeEntity.getId(), cid);
							if (Func.isNotEmpty(typeTemp)) {
								certificateTempEntity=typeTemp;
								tempMap.put(Func.toStr(typeTemp.getCertificateTypeId()), typeTemp);
							} else {
								throw new ExcelException("第"+(i+2)+"行："+"匹配证件类型[" + vehicleExcel.getType() + "]失败，无法导入,请检查申请的证件类型是否输入正确");
							}
						}
						certificateApplyEntity.setRealName(certificateTempEntity.getRealName());
						certificateApplyEntity.setTypeName(trim(certificateTypeEntity.getTypeName()));
						certificateApplyEntity.setTypeKey(certificateTypeEntity.getTypeKey());
					} else {
						throw new ExcelException("第"+(i+2)+"行："+"匹配证件类型[" + vehicleExcel.getType() + "]失败，无法导入,请检查申请的证件类型是否输入正确");
					}
				}
				addData.add(certificateApplyEntity);
			}

			Map<String, List<CertificateApplyEntity>> vlidDatas = addData.stream().collect(Collectors.groupingBy(CertificateApplyEntity::getTypeName));
			for (Map.Entry<String, List<CertificateApplyEntity>> entry : vlidDatas.entrySet()) {
				int size = entry.getValue().size();
				CertificateTypeEntity certificateTypeEntity = typeEntityMap.get(entry.getKey());
				CertificateTempEntity certificateTempEntity = tempMap.get(Func.toStr(certificateTypeEntity.getId()));
				String tempCount = tempCountMap.get(Func.toStr(certificateTypeEntity.getId()));
				int anInt = Func.toInt(tempCount);
				BigDecimal totalUsaValu = getBigDecimal(anInt).add(BigDecimal.valueOf(size));
				if (certificateTempEntity.getMaxValu().intValue() == anInt || totalUsaValu.intValue() > certificateTempEntity.getMaxValu().intValue()) {
					throw new ExcelException("您的[" + certificateTypeEntity.getTypeName() + "]可申请数量不足!");
				}
			}
			saveBatch(addData);
		}
	}

	/*国籍字典code*/
	private final static String NATIONALITY_CODE = "nationality";

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void importPeData(List<PersonnelExcelTemp> data, Boolean isCovered, String type, String cid) {
		if (Func.isNull(data.get(0).getIdCard())) {
			throw new ExcelException("导入数据模板不正确!");
		}
		List<CertificateTypeEntity> types = getTypes(type);
		if (Func.isEmpty(types)) {
			if (Func.equals(type, PER_CERTIFICATE_TYPE)) {
				throw new ExcelException("您没有人员证件类型的申请权限!");
			}
			if (Func.equals(type, SER_CERTIFICATE_TYPE)) {
				throw new ExcelException("您没有服务证件类型的申请权限!");
			}
		}

		List<DictBiz> nationalityList = DictBizCache.getList(NATIONALITY_CODE);
		Map<String, CertificateTypeEntity> typeEntityMap = new HashMap<>();
		if (Func.isNotEmpty(types)) {
			typeEntityMap = types.stream().collect(Collectors.toMap(o -> trim(o.getTypeName()), s -> s, (v1, v2) -> v1));
		}
		List<CertificateApplyEntity> list = getApplys(type,cid);
		Map<String, CertificateApplyEntity> map = new HashMap<>();
		Map<String, DictBiz> dictMap = new HashMap<>();

		if (Func.isNotEmpty(list)) {
			map = list.stream().collect(Collectors.toMap(CertificateApplyEntity::getIdCard, t -> t, (k1, k2) -> k1));
		}
		if (Func.isNotEmpty(nationalityList)) {
			dictMap = nationalityList.stream().collect(Collectors.toMap(DictBiz::getDictValue, t -> t, (k1, k2) -> k1));
		}
		if (Func.isNotEmpty(data)) {
			List<CertificateApplyEntity> addData = new ArrayList<>();
			Map<String, String> tempCountMap = new HashMap<>();
			Map<String, CertificateTempEntity> tempMap = new HashMap<>();

			for (int i= 0;i< data.size();i++) {
				PersonnelExcelTemp peExcel=data.get(i);
				if (Func.isEmpty(peExcel.getName())) {
					throw new ExcelException("第"+(i+2)+"行："+"请填入姓名!");
				}
				if (Func.isEmpty(peExcel.getType())) {
					throw new ExcelException("第"+(i+2)+"行："+"请输入申请证件类型名称!");
				}
				if (Func.isEmpty(peExcel.getIdCard())) {
					throw new ExcelException("第"+(i+2)+"行："+"请输入申请证件类型!");
				}
				if (Func.isEmpty(peExcel.getPhone())) {
					throw new ExcelException("第"+(i+2)+"行："+"请填入联系电话!");
				}
//				DictBiz dict = dictMap.get(peExcel.getNationality());
//				if (Func.isNotEmpty(dict)) {
//					peExcel.setNationality(dict.getDictKey());
//				} else {
//					peExcel.setNationality("4");
//				}

				List<String> exclud = Arrays.asList("中国");
				if (exclud.contains(peExcel.getNationality())) {
					if (IdCardCheckUtil.isPhone(peExcel.getPhone()) && IdCardCheckUtil.isMobile(peExcel.getPhone())) {
						throw new ExcelException("第"+(i+2)+"行："+peExcel.getName() + "的联系电话不正确!");
					}
				}
				if (exclud.contains(peExcel.getNationality())) {
					IdCarUtils.Res res = IdCarUtils.idCarVerify(peExcel.getName(), peExcel.getIdCard());
					if (res.getCode() != 0) {
						throw new ExcelException("第"+(i+2)+"行："+res.getMessage());
					}
					IdCarUtils.CarInfo result = res.getResult();
					if (!Func.equals(result.getRes(), "1")) {
						throw new ExcelException("第"+(i+2)+"行："+"姓名："+peExcel.getName()+"身份证号："+peExcel.getIdCard()+"身份证号与姓名不一致");
					}
				}
				CertificateApplyEntity certificateApplyEntity1 = map.get(trim(peExcel.getIdCard()));
				if (!Func.isNull(certificateApplyEntity1)) {
					if (Func.equals(certificateApplyEntity1.getName(), trim(peExcel.getName()))) {
						throw new ExcelException("第"+(i+2)+"行："+peExcel.getName() + "，证件号[" + peExcel.getIdCard() + "]在系统中已经存在了，请不要重复导入");
					}
				}
				CertificateApplyEntity certificateApplyEntity = Objects.requireNonNull(BeanUtil.copy(peExcel, CertificateApplyEntity.class));
				certificateApplyEntity.setStatus(0);
				certificateApplyEntity.setBizStatus(0);
				certificateApplyEntity.setAuditorCount(1);
				certificateApplyEntity.setIdCard(trim(peExcel.getIdCard()));
				certificateApplyEntity.setAgentUserId(AuthUtil.getUserId());
				certificateApplyEntity.setAgentUser(AuthUtil.getUser().getUserName());
				if (Func.isNotEmpty(cid)) {
					certificateApplyEntity.setCreateUser(Func.toLong(cid));
				}
				certificateApplyEntity.setBizCode(type);
				if (Func.isNotEmpty(typeEntityMap)) {
					CertificateTypeEntity certificateTypeEntity = typeEntityMap.get(trim(peExcel.getType()));
					if (Func.isNotEmpty(certificateTypeEntity)) {
						certificateApplyEntity.setCertificateTypeId(certificateTypeEntity.getId());
						CertificateTempEntity certificateTempEntity = tempMap.get(Func.toStr(certificateTypeEntity.getId()));
						String count = tempCountMap.get(Func.toStr(certificateApplyEntity.getCertificateTypeId()));
						if (Func.isEmpty(count)) {
							Long aLong = countBy(certificateTypeEntity.getId(),Func.toLong(cid));
							tempCountMap.put(Func.toStr(certificateTypeEntity.getId()), Func.toStr(aLong));
						}
						if (Func.isEmpty(certificateTempEntity)) {
							CertificateTempEntity typeTemp = getTypeTemp(certificateTypeEntity.getId(), cid);
							if (Func.isNotEmpty(typeTemp)) {
								certificateTempEntity=typeTemp;
								tempMap.put(Func.toStr(typeTemp.getCertificateTypeId()), typeTemp);
							} else {
								throw new ExcelException("第"+(i+2)+"行："+"匹配证件类型[" + peExcel.getType() + "]失败，无法导入,请检查申请的证件类型是否输入正确");
							}
						}
						certificateApplyEntity.setRealName(certificateTempEntity.getRealName());
						certificateApplyEntity.setTypeName(trim(certificateTypeEntity.getTypeName()));
						certificateApplyEntity.setTypeKey(certificateTypeEntity.getTypeKey());
					} else {
						throw new ExcelException("第"+(i+2)+"行："+"匹配证件类型[" + peExcel.getType() + "]失败，无法导入,请检查申请的证件类型是否输入正确");
					}
				}
				addData.add(certificateApplyEntity);
			}
			Map<String, List<CertificateApplyEntity>> vlidDatas = addData.stream().collect(Collectors.groupingBy(CertificateApplyEntity::getTypeName));

			for (Map.Entry<String, List<CertificateApplyEntity>> entry : vlidDatas.entrySet()) {
				int size = entry.getValue().size();
				CertificateTypeEntity certificateTypeEntity = typeEntityMap.get(entry.getKey());
				CertificateTempEntity certificateTempEntity = tempMap.get(Func.toStr(certificateTypeEntity.getId()));
				String tempCount = tempCountMap.get(Func.toStr(certificateTypeEntity.getId()));
				int anInt = Func.toInt(tempCount);
				BigDecimal totalUsaValu = getBigDecimal(anInt).add(BigDecimal.valueOf(size));
				if (certificateTempEntity.getMaxValu().intValue() == anInt || totalUsaValu.intValue() > certificateTempEntity.getMaxValu().intValue()) {
					throw new ExcelException("您的[" + certificateTypeEntity.getTypeName() + "]可申请数量不足!");
				}
			}
			saveBatch(addData);
		}
	}

	@Override
	public Long countBy(Long certificateTypeId, Long createUserId) {
		CertificateApplyEntity query = new CertificateApplyEntity();
		query.setCreateUser(createUserId);
		query.setCertificateTypeId(certificateTypeId);
		query.setTenantId(AuthUtil.getTenantId());
		query.setIsDeleted(0);
		QueryWrapper<CertificateApplyEntity> queryWrapper = Condition.getQueryWrapper(query);
		return count(queryWrapper);
	}

	@Override
	public Map<String, List<CertificateApplyEntity>> countByUserIds(List<Long> certificateTypeIds) {
		LambdaQueryChainWrapper<CertificateApplyEntity> queryWrapper = lambdaQuery();
		if (certificateTypeIds.size() > 1) {
			queryWrapper.in(CertificateApplyEntity::getCertificateTypeId, certificateTypeIds);
		} else {
			queryWrapper.eq(CertificateApplyEntity::getCertificateTypeId, certificateTypeIds.get(0));
		}
		List<CertificateApplyEntity> list = queryWrapper.list();
		if (Func.isEmpty(list)) {
			return Collections.emptyMap();
		}
		return list.stream().collect(Collectors.groupingBy(t -> Func.toStr(t.getCertificateTypeId())));
		//Map<Long, Integer> res = new HashMap<>();
		//for (Map.Entry<Long, List<CertificateApplyEntity>> entry : collect.entrySet()) {
		//	res.put(entry.getKey(), entry.getValue().size());
		//}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean resAudit(List<Long> ids) {
		LambdaQueryWrapper<CertificateApplyEntity> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.eq(CertificateApplyEntity::getCreateUser, AuthUtil.getUserId());
		List<CertificateApplyEntity> list = list(queryWrapper);
		if (Func.isEmpty(list)) {
			throw new ServiceException("数据不存在");
		}
		List<CertificateApplyEntity> updateData = list.stream().peek(o -> {
			if (o.getBizStatus() == 1) {
				throw new ServiceException(getMsg(o) + "已经审核通过了，无需再重新提交");
			}
			if (o.getBizStatus() == 3) {
				throw new ServiceException(getMsg(o) + "正在审核中，无需再重新提交");
			}
			int count = o.getAuditorCount() + 1;
			o.setAuditorCount(count);
			o.setBizStatus(0);
		}).collect(Collectors.toList());
		return updateBatchById(updateData);
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean delete(List<Long> ids) {

		LambdaQueryWrapper<CertificateApplyEntity> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.in(CertificateApplyEntity::getId, ids);
		List<CertificateApplyEntity> list = list(queryWrapper);
		if (Func.isEmpty(list)) {
			throw new ServiceException("数据不存在");
		}
		list.stream().map(m -> {
//			if (m.getBizStatus() == 1) {
//				throw new ServiceException("该证件证件已审核通过了，不能删除");
//			}
			m.setIsDeleted(1);
			return m;
		}).collect(Collectors.toList());

		return deleteLogic(ids);
	}

	@Override
	public List<MateVO> putFileAttach(MultipartFile file) {
		String fileName = file.getOriginalFilename();
		String trim = fileName.toUpperCase().trim();
		String substring = trim.substring(0, trim.lastIndexOf("."));
		LambdaQueryWrapper<CertificateApplyEntity> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.eq(CertificateApplyEntity::getIdCard, substring);
		List<CertificateApplyEntity> list = list(queryWrapper);
		if(Func.isEmpty(list)){
			return  null;
//			throw new ServiceException(getResultCode());
		}
		R r = ossClient.ossPutFile(file);
		log.info("远程请求返回结果：{}",r);
		List<MateVO> mateVOList = new ArrayList<>();
		MateVO mateVO = BeanUtil.instantiateClass(MateVO.class);
		list.forEach(o->{
			mateVO.setId(Func.toStr(o.getId()));
			mateVO.setUrl(Func.toStr(r.getData()));
			mateVOList.add(mateVO);
		});
		return mateVOList;
	}

	private String getMsg(CertificateApplyEntity entity) {
		return Func.equals(entity.getBizCode(), CAR_CERTIFICATE_TYPE) ? "车牌:" + entity.getLicensePlate() : entity.getName() + " 的" + entity.getTypeName();
	}

	private List<CertificateTypeEntity> getTypes(String bizCode) {
		CertificateTypeEntity query = new CertificateTypeEntity();
		query.setBizCode(bizCode);
		QueryWrapper<CertificateTypeEntity> queryWrapper = Condition.getQueryWrapper(query);
		return certificateTypeService.list(queryWrapper);
	}

	private List<CertificateApplyEntity> getApplys(String bizCode,String cid) {
		CertificateApplyEntity query = new CertificateApplyEntity();
		query.setBizCode(bizCode);
		query.setCreateUser(Func.toLong(cid));
		QueryWrapper<CertificateApplyEntity> queryWrapper = Condition.getQueryWrapper(query);
		return list(queryWrapper);
	}

	/**
	 * @param certificateTypeId: 证件类型ID
	 * @param cid:               展商ID
	 * @method: getTypeTemp
	 * @description:
	 * @date: 2023/8/2
	 * @author: WK
	 * @return: {@link CertificateTempEntity}
	 */
	private CertificateTempEntity getTypeTemp(Long certificateTypeId, String cid) {
		CertificateTempEntity query = new CertificateTempEntity();
		query.setCertificateTypeId(certificateTypeId);
		if (Func.isEmpty(cid)) {
			query.setUserId(AuthUtil.getUserId());
		} else {
			query.setUserId(Func.toLong(cid));
		}
		QueryWrapper<CertificateTempEntity> queryWrapper = Condition.getQueryWrapper(query);
		return certificateTempService.getOne(queryWrapper);
	}

}
